package fmi.chesstern.pieces;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import fmi.chesstern.game.BoardField;
import fmi.chesstern.game.GameBoardState;
import fmi.chesstern.game.Move;

public class ChessPiece {
	private final ChessPieceType type;
	private final ChessPieceColor color;
	
	private static final Map<ChessPieceType, ChessPiece> whitePieces = new HashMap<ChessPieceType, ChessPiece>();
	private static final Map<ChessPieceType, ChessPiece> blackPieces = new HashMap<ChessPieceType, ChessPiece>();
	
	private ChessPiece(ChessPieceType pieceType, ChessPieceColor color) {
		this.type = pieceType;
		this.color = color;
	}
	
	private static Map<ChessPieceType, ChessPiece> getInternedPiecesByColor(ChessPieceColor color) {
		return color == ChessPieceColor.WHITE ? whitePieces : blackPieces;
	}
	
	public static ChessPiece getPiece(ChessPieceType type, ChessPieceColor color) {
		Map<ChessPieceType, ChessPiece> internedPieces = getInternedPiecesByColor(color);
		
		if (!internedPieces.containsKey(type)) {
			internedPieces.put(type, new ChessPiece(type, color));
		}
		
		return internedPieces.get(type);
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((color == null) ? 0 : color.hashCode());
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof ChessPiece)) {
			return false;
		}
		ChessPiece other = (ChessPiece) obj;

		return color.equals(other.color) && type.equals(other.type);
	}

	public ChessPieceColor getColor() {
		return color;
	}

	public ChessPieceType getType() {
		return type;
	}

	public Set<Move> getValidMoves(GameBoardState board, BoardField currentPosition) {
		return type.getValidMoves(board, currentPosition);
	}
}
